package pl.polidea.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.FrameLayout;

/**
 * View measures underlying view hierarchy drawing performance and shows it on
 * transparent overlay.
 */
public class PerformanceOverlayView extends FrameLayout {

    class TimeValuesChart {
        // chart buffer size
        static final int N = 256;

        // buffers
        private final long[] times = new long[N];
        private final int[] values = new int[N];
        private int j;

        public TimeValuesChart() {
        }

        void insertValue(final long t, final int val) {
            times[j] = t;
            values[j] = val;
            --j;
            if (j < 0) {
                j += N;
            }
        }

        void draw(final Canvas canvas, final Paint paint, final float left, final float top, final float right,
                final float bottom, final int min, final int max, final long t, final long dt) {

            final float t1 = 1.0f / dt;
            final float max1 = 1.0f / max;
            final float w = right - left;
            final float h = bottom - top;

            float startX = left + w;
            float startY = top + (1.0f - (values[(j + 1) % N] - min) * max1) * h;
            float stopX;
            float stopY;

            for (int i = (j + 2) % N; i != j; i = (i + 1) % N) {
                if (t - times[i] > dt) {
                    break;
                }

                stopX = left + (1.0f - (t - times[i]) * t1) * w - 1.0f;
                stopY = top + (1.0f - (values[i] - min) * max1) * h - 1.0f;

                canvas.drawLine(startX, startY, stopX, stopY, paint);

                startX = stopX;
                startY = stopY;
            }
        }
    }

    private long mLastDrawTime;
    private final TimeValuesChart fpsChart = new TimeValuesChart();
    private final TimeValuesChart memChart = new TimeValuesChart();
    private final TimeValuesChart imgsChart = new TimeValuesChart();

    public PerformanceOverlayView(final Context context) {
        super(context);
    }

    public PerformanceOverlayView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void dispatchDraw(final Canvas canvas) {
        // catch time
        final long t = System.currentTimeMillis();

        // draw normally
        super.dispatchDraw(canvas);

        // catch time difference
        final long dt = t - mLastDrawTime;
        mLastDrawTime = t;

        // create paint
        final Paint paint = new Paint();

        // background
        paint.setARGB(192, 0, 0, 0);
        canvas.drawRect(0.0f, 0.0f, 150.0f, 65.0f, paint);

        // print FPS
        final int fps = (int) (1000 / dt);
        fpsChart.insertValue(t, fps);
        paint.setARGB(255, 255, 255, 255);
        canvas.drawText(fps + " FPS", 10, 12, paint);

        // draw fps chart
        paint.setARGB(255, 255, 0, 0);
        fpsChart.draw(canvas, paint, 0.0f, 15.0f, 150.0f, 65.0f, 0, 70, t, 2000);

        // redraw
        invalidate();
    }
}
